'''###########################################################################################################################
### File: level_gen.py
### Name: Patrick Delaney, Andrew Oberlin
### Class: CSE 487
### Instructor: Dr.Zmuda
### Assignment: Final Project
### Description: Class for handling the level generation
################ 
'''
from menu_scroller import MenuScroller
from menu_button import MenuButton
from panda3d.core import Vec2, Point3, Vec3, Vec4
from direct.gui.DirectGui import *
from pandac.PandaModules import TextNode
import os
from panda3d.core import Filename
from shutil import copy
from Tkinter import Tk
from tkFileDialog import askopenfilename

class AnimationGen:

	'''
	### Name: __init__ (Constructor)
	### Author: Andrew Oberlin, Patrick Delaney
	### Parameters: None
	### Description: 
	'''
	def __init__(self, parent, projectDirectory, animation, character):
		self.parent = parent
		self.models = dict()
		self.labels = dict()
		self.projectDirectory = projectDirectory
		self.animation = animation
		self.character = character
		self.currentFrame = -1
		# array implementation of list queue for the textures
		self.textures = []
		if (not os.path.exists("projects/" + projectDirectory +"/characters/tmp")):
			os.mkdir("projects/" + projectDirectory +"/characters/tmp")
		
		self.__loadModels()
		
		self.parent.accept("arrow_left", self.cycleFrame, [-1])
		self.parent.accept("arrow_right", self.cycleFrame, [1])
		
	'''
	### Name: __loadModels
	### Author: Andrew Oberlin, Patrick Delaney
	### Parameters: None
	### Description: 
	'''
	def __loadModels(self):		
		# name input
		self.models['name_input_dummy'] = self.parent.base.aspect2d.attachNewNode('name_input_dummy')
		self.models['name_input_dummy'].setPos(-1.25, 0, 0.5)
		
		self.labels['name_label_text'] = TextNode('name_label_text')
		self.labels['name_label_text'].setText("Animation's Name")
		self.models['name_label'] = self.models['name_input_dummy'].attachNewNode(self.labels['name_label_text'])
		self.models['name_label'].setScale(Vec3(0.10,0.10,0.075))
		
		self.models['name_input'] = DirectEntry(initialText=self.animation.getName(), cursorKeys=True, scale=Vec3(0.10, 0.075, 0.075))
		self.models['name_input'].setPos(Vec3(0.85, 0, 0))
		self.models['name_input'].reparentTo(self.models['name_input_dummy'])
		
		# type input
		self.models['type_input_dummy'] = self.parent.base.aspect2d.attachNewNode('type_input_dummy')
		self.models['type_input_dummy'].setPos(-1.25, 0, 0.35)
		
		self.labels['type_label_text'] = TextNode('type_label_text')
		self.labels['type_label_text'].setText("Animation's Type")
		self.models['type_label'] = self.models['type_input_dummy'].attachNewNode(self.labels['type_label_text'])
		self.models['type_label'].setScale(Vec3(0.10,0.10,0.075))
		
		self.models['type_input'] = DirectEntry(initialText=self.animation.getType(), cursorKeys=True, scale=Vec3(0.10, 0.075, 0.075))
		self.models['type_input'].setPos(Vec3(0.85, 0, 0))
		self.models['type_input'].reparentTo(self.models['type_input_dummy'])
	
		self.models['add_texture_button'] = MenuButton(
			self.parent, 'add_texture_button', 'models/gui/game_maker/dialog_button', 
			self.addTexture, Vec3(-1.0, 0, 0.20), isMovie = False, text="Add Texture", 
			textPos=Vec3(-0.2, 0, -0.025), scale=Vec3(0.8,1,0.1)
		)
		
		self.models['preview_button'] = MenuButton(
			self.parent, 'preview_button', 'models/gui/game_maker/dialog_button', 
			self.preview, Vec3(-1.0, 0, 0.05), isMovie = False, text="Preview", 
			textPos=Vec3(-0.115, 0, -0.025), scale=Vec3(0.8,1,0.1)
		)
		
		self.models['replace_button'] = MenuButton(
			self.parent, 'replace_button', 'models/gui/game_maker/dialog_button', 
			self.replace, Vec3(-1.0, 0, -0.10), isMovie = False, text="Replace", 
			textPos=Vec3(-0.115, 0, -0.025), scale=Vec3(0.8,1,0.1)
		)
		
		self.models['save_button'] = MenuButton(
			self.parent, 'save_button', 'models/gui/game_maker/dialog_button', 
			self.save, Vec3(1.0, 0, -0.50), isMovie = False, text="Save", 
			textPos=Vec3(-0.115, 0, -0.025), scale=Vec3(0.8,1,0.1)
		)
		
		self.models['preview'] = self.parent.loader.loadModelCopy("models/plane")
		self.models['preview'].reparentTo(self.parent.base.aspect2d)
		self.models['preview'].setPos(0.1, 0, -0.50)
		self.models['preview'].setScale(0.75)
		
	'''
		Adds a texture after the current frame
	'''
	def addTexture(self):
		try:
			root=Tk()
			self.file_opt = options = {}
			options['defaultextension'] = '' # couldn't figure out how this works
			options['filetypes'] = [('.png Files', '.png')]
			options['parent'] = root
			options['title'] = 'Choose a texture!'
			textureFile = askopenfilename(**self.file_opt)
			basename = Filename(textureFile).getBasename()
			copy(textureFile, os.path.abspath("projects/" + self.projectDirectory + "/characters/tmp/" + basename))
			textureFile = "projects/" + self.projectDirectory + "/characters/tmp/" + basename
			root.destroy()
			texture = self.parent.loader.loadTexture(textureFile)
			self.models['preview'].setTransparency(1)
			self.models['preview'].setTexture(texture)
			self.insertTexture(textureFile)
		except IOError, e:
			print "Problem loading texture!"
		
	'''
		Previews the animation in the preview window
	'''
	def preview(self):
		self.movies = [self.parent.loader.loadTexture(self.textures[i]) for i in range(len(self.textures))]
		task = self.parent.taskMgr.add(self.animationTask, "preview_animation")
		task.fps = 10
		
	'''
		Animation task for changing the current image
	'''
	def animationTask(self, task):
		currentFrame = int(task.time * task.fps)
		if (currentFrame < len(self.textures)):
			self.models['preview'].setTexture(self.movies[currentFrame])
			return task.cont
		else:
			return task.done
		

	'''
		Replaces the texture at the current frame
	'''
	def replace(self):
		try:
			root=Tk()
			self.file_opt = options = {}
			options['defaultextension'] = '' # couldn't figure out how this works
			options['filetypes'] = [('.png Files', '.png')]
			options['parent'] = root
			options['title'] = 'Choose a texture!'
			textureFile = askopenfilename(**self.file_opt)
			basename = Filename(textureFile).getBasename()
			copy(textureFile, os.path.abspath("projects/" + self.projectDirectory + "/characters/tmp/" + basename))
			textureFile = "projects/" + self.projectDirectory + "/characters/tmp/" + basename
			root.destroy()
			texture = self.parent.loader.loadTexture(textureFile)
			self.models['preview'].setTransparency(1)
			self.models['preview'].setTexture(texture)
			oldTexture = Filename(self.textures[self.currentFrame]).toOsSpecific()
			os.remove(oldTexture)
			self.textures[self.currentFrame] = textureFile
		except IOError, e:
			print "Problem loading texture!"
	
	'''
	
	'''
	def save(self):	
		self.animation.setName(self.models['name_input'].get(plain=True))
		self.animation.setType(self.models['type_input'].get(plain=True))
		
		absPath = os.path.abspath("projects/" + self.projectDirectory + "/characters/main/")
		try:
			os.mkdir(absPath + "\\" + self.character.name + "\\" + self.animation.name)
		except:
			print "problem saving the animation"
			
		for item in self.textures:
			basename = Filename(item).getBasename()
			try:
				copy(Filename(item).toOsSpecific(), absPath + "\\" + self.character.name + "\\" + self.animation.name + "\\" + basename)
			except:
				print "error moving texture file"
			self.animation.addTexture("projects/" + self.projectDirectory + "/characters/main/" + self.character.name + "/" + self.animation.name + "/" + basename)
		
		self.animation.save(self.projectDirectory, self.character.name)
		
	'''
	
	'''
	def cycleFrame(self, increment):
		if (self.currentFrame + increment < len(self.textures) and self.currentFrame + increment >= 0):
			self.currentFrame += increment
			texture = self.parent.loader.loadTexture(self.textures[self.currentFrame])
			self.models['preview'].setTransparency(1)
			self.models['preview'].setTexture(texture)
			
		
	'''
		Inserts a new texture into the texture array at the correct position
	'''
	def insertTexture(self, texture):
		if (self.currentFrame < len(self.textures) - 1):
			newTextures = []
			for i in range(self.currentFrame + 1):
				newTextures.append(self.textures[i])
				
			newTextures.append(texture)
			
			for i in range(self.currentFrame + 2, len(self.textures)):
				newTextures.append(self.textures[i])
				
			self.textures = newTextures
		else:
			self.textures.append(texture)
			
		self.currentFrame += 1
		
		
		